<template>
  <div class="containers">
    <div class="canvas" ref="bpmnCanvas"></div>
    <div class="toolbar">
      <!-- 添加返回按钮组 -->
      <div class="tool-group">
        <div class="group-title">返回</div>
        <div class="button-group">
          <el-tooltip content="返回列表" placement="bottom" :show-after="500">
            <el-button :icon="Back" circle @click="handleBack" />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 对齐工具组 -->
      <div class="tool-group">
        <div class="group-title">对齐</div>
        <div class="button-group">
          <el-tooltip content="左对齐" placement="bottom" :show-after="500">
            <el-button :icon="ArrowLeft" circle @click="handleAlign('left')" />
          </el-tooltip>
          <el-tooltip content="水平居中" placement="bottom" :show-after="500">
            <el-button :icon="Sort" circle @click="handleAlign('center')" />
          </el-tooltip>
          <el-tooltip content="右对齐" placement="bottom" :show-after="500">
            <el-button :icon="ArrowRight" circle @click="handleAlign('right')" />
          </el-tooltip>
          <el-tooltip content="顶部对齐" placement="bottom" :show-after="500">
            <el-button :icon="ArrowUp" circle @click="handleAlign('top')" />
          </el-tooltip>
          <el-tooltip content="垂直居中" placement="bottom" :show-after="500">
            <el-button :icon="SortUp" circle @click="handleAlign('middle')" />
          </el-tooltip>
          <el-tooltip content="底部对齐" placement="bottom" :show-after="500">
            <el-button :icon="ArrowDown" circle @click="handleAlign('bottom')" />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 视图控制组 -->
      <div class="tool-group">
        <div class="group-title">视图</div>
        <div class="button-group">
          <el-tooltip content="缩小视图 (Ctrl+-)" placement="bottom" :show-after="500">
            <el-button :icon="ZoomOut" circle @click="zoom(-0.1)" />
          </el-tooltip>
          <el-tooltip content="重置视图" placement="bottom" :show-after="500">
            <el-button :icon="FullScreen" circle @click="resetView" />
          </el-tooltip>
          <el-tooltip content="放大视图" placement="bottom" :show-after="500">
            <el-button :icon="ZoomIn" circle @click="zoom(0.1)" />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 编辑控制组 -->
      <div class="tool-group">
        <div class="group-title">编辑</div>
        <div class="button-group">
          <el-tooltip content="撤销" placement="bottom" :show-after="500">
            <el-button :icon="Back" circle @click="undo" />
          </el-tooltip>
          <el-tooltip content="恢复" placement="bottom" :show-after="500">
            <el-button :icon="Right" circle @click="redo" />
          </el-tooltip>
          <el-tooltip content="重新绘制" placement="bottom" :show-after="500">
            <el-button :icon="Refresh" circle @click="resetBpmn" />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 导出组 -->
      <div class="tool-group">
        <div class="group-title">导出</div>
        <div class="button-group">
          <el-tooltip content="预览XML" placement="bottom" :show-after="500">
            <el-button :icon="Document" circle @click="previewXML" />
          </el-tooltip>
          <el-tooltip content="预览JSON" placement="bottom" :show-after="500">
            <el-button :icon="Operation" circle @click="previewJSON" />
          </el-tooltip>
          <el-tooltip content="下载XML" placement="bottom" :show-after="500">
            <el-button :icon="Download" circle @click="downloadFile('xml')" />
          </el-tooltip>
          <el-tooltip content="下载SVG" placement="bottom" :show-after="500">
            <el-button :icon="PictureFilled" circle @click="downloadFile('svg')" />
          </el-tooltip>
          <el-tooltip content="下载BPMN" placement="bottom" :show-after="500">
            <el-button :icon="Document" circle @click="downloadFile('bpmn')" />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 流程模拟 -->
      <div class="tool-group">
        <div class="group-title">流程模拟</div>
        <div class="button-group">
          <el-tooltip content="流程模拟" placement="bottom" :show-after="500">
            <el-button
              :icon="VideoPlay"
              circle
              :type="simulationActive ? 'primary' : 'default'"
              @click="toggleSimulation"
            />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 添加属性面板控制组 -->
      <div class="tool-group">
        <div class="group-title">属性</div>
        <div class="button-group">
          <el-tooltip content="属性面板" placement="bottom" :show-after="500">
            <el-button
              :icon="Setting"
              circle
              :type="drawerVisible ? 'primary' : 'default'"
              @click="toggleDrawer"
            />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 导入工具组 -->
      <div class="tool-group">
        <div class="group-title">导入</div>
        <div class="button-group">
          <el-tooltip content="导入BPMN" placement="bottom" :show-after="500">
            <el-upload
              class="upload-button"
              action=""
              :show-file-list="false"
              :before-upload="handleFileUpload"
            >
              <el-button :icon="Upload" circle />
            </el-upload>
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 校验工组 -->
      <div class="tool-group">
        <div class="group-title">校验</div>
        <div class="button-group">
          <el-tooltip content="流程校验" placement="bottom" :show-after="500">
            <el-button :icon="Check" circle @click="validateProcess" />
          </el-tooltip>
        </div>
      </div>

      <el-divider direction="vertical" />

      <!-- 添加小地图控制组 -->
      <div class="tool-group">
        <div class="group-title">导航</div>
        <div class="button-group">
          <el-tooltip content="小地图" placement="bottom" :show-after="500">
            <el-button
              :icon="Location"
              circle
              :type="showMinimap ? 'primary' : 'default'"
              @click="toggleMinimap"
            />
          </el-tooltip>
        </div>
      </div>

      <!-- 添加流程设计工具组 -->
      <div class="tool-group">
        <div class="group-title">保存</div>
        <div class="button-group">
          <el-tooltip content="保存流程设计" placement="bottom" :show-after="500">
            <el-button :icon="Upload" circle @click="submitDeploy" />
          </el-tooltip>
        </div>
      </div>
    </div>

    <!-- 添加快捷键提示 -->
    <div class="shortcut-tips" :class="{ 'tips-visible': showShortcuts }">
      <div class="tips-header">
        <span>快捷键</span>
        <el-button type="primary" link :icon="Close" @click="showShortcuts = false" />
      </div>
      <div class="tips-content">
        <div class="tip-item">
          <span class="key">Ctrl + Z</span>
          <span class="desc">撤销</span>
        </div>
        <div class="tip-item">
          <span class="key">Ctrl + Y</span>
          <span class="desc">重做</span>
        </div>
        <div class="tip-item">
          <span class="key">Ctrl + -</span>
          <span class="desc">缩小</span>
        </div>
        <div class="tip-item">
          <span class="key">Ctrl + =</span>
          <span class="desc">放大</span>
        </div>
        <div class="tip-item">
          <span class="key">Del</span>
          <span class="desc">删除</span>
        </div>
      </div>
    </div>

    <!-- XML预览对话框 -->
    <el-dialog
      v-model="previewXMLVisible"
      title="预览XML"
      width="80%"
      :close-on-click-modal="false"
      :destroy-on-close="true"
      class="preview-dialog"
    >
      <el-scrollbar height="60vh">
        <pre class="xml-content" v-html="highlightedXML"></pre>
      </el-scrollbar>
      <template #footer>
        <el-button @click="previewXMLVisible = false">关闭</el-button>
        <el-button type="primary" @click="copyXML">复制内容</el-button>
      </template>
    </el-dialog>

    <!-- JSON预览对话框 -->
    <el-dialog
      v-model="previewJSONVisible"
      title="预览JSON"
      width="80%"
      :close-on-click-modal="false"
      :destroy-on-close="true"
      class="preview-dialog"
    >
      <el-scrollbar height="60vh">
        <pre class="json-content" v-html="highlightedJSON"></pre>
      </el-scrollbar>
      <template #footer>
        <el-button @click="previewJSONVisible = false">关闭</el-button>
        <el-button type="primary" @click="copyJSON">复制内容</el-button>
      </template>
    </el-dialog>

    <!-- 使用属性面板组件 -->
    <PropertyPanel
      v-if="modeler"
      v-model:visible="drawerVisible"
      :current-element="currentElement"
      :modeler="modeler"
      class="property-panel"
    />

    <!-- 添加校验结果对话框 -->
    <el-dialog
      v-model="validateVisible"
      title="校验结果"
      width="500px"
      destroy-on-close
      align-center
    >
      <div class="validate-result">
        <template v-if="validateErrors.length">
          <div v-for="(error, index) in validateErrors" :key="index" class="error-item">
            <el-alert
              :title="error.message"
              type="error"
              :description="'流程:' + error.id"
              show-icon
              @click="locateElement(error.id)"
            />
          </div>
        </template>
        <template v-else>
          <el-result icon="success" title="校验通过" sub-title="流程图符合规范要求" />
        </template>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, onBeforeUnmount, markRaw, nextTick } from 'vue'
import BpmnModeler from 'bpmn-js/lib/Modeler'
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import type Canvas from 'diagram-js/lib/core/Canvas'
//小地图
import minimapModule from 'diagram-js-minimap'
import BpmnModdle from 'bpmn-moddle'
import 'diagram-js-minimap/assets/diagram-js-minimap.css'
// 流程模拟
import TokenSimulationModule from 'bpmn-js-token-simulation'
import ToggleMode from 'bpmn-js-token-simulation/lib/features/toggle-mode/modeler/ToggleMode'
import 'bpmn-js-token-simulation/assets/css/bpmn-js-token-simulation.css'
// 流程图校验部分
import lintModule from 'bpmn-js-bpmnlint'
import bpmnlint from '@/views/ProcessDesign/modules/Lint/bpmnlint'
import 'bpmn-js-bpmnlint/dist/assets/css/bpmn-js-bpmnlint.css'
// 创建和追加任何元素(省略号更多)
import { CreateAppendAnythingModule } from 'bpmn-js-create-append-anything'
// 重写 paletteProvider
import RewritePalette from '@/views/ProcessDesign/modules/Palette/index'
// 重写 contextPadProvider
import EnhancementContextPad from '@/views/ProcessDesign/modules/ContextPad/index'
// 增渲染器
import CustomRenderer from '@/views/ProcessDesign/modules/Renderer/index'
// 网格背景
import GridLineModule from 'diagram-js-grid-bg'
// 颜色选择器
import BpmnColorPickerModule from 'bpmn-js-color-picker'
import 'bpmn-js-color-picker/colors/color-picker.css'
import xmlStr from '@/resource/defaultEmpty'
import translate from '@/views/ProcessDesign/modules/Translate'
import { customTranslate } from '@/views/ProcessDesign/modules/Translate/index'
import {
  ArrowLeft,
  ArrowRight,
  ArrowUp,
  ArrowDown,
  Sort,
  SortUp,
  ZoomIn,
  ZoomOut,
  FullScreen,
  Back,
  Right,
  Refresh,
  Document,
  Operation,
  Download,
  PictureFilled,
  VideoPlay,
  Close,
  Setting,
  Upload,
  Check,
  Location,
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { copyToClipboard } from '@/utils/clipboard'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import PropertyPanel from './ProcessDesign/components/PropertyPanel.vue'
import FlowableModdle from './ProcessDesign/config/flowable.json'
import type { Element, Connection, Label, Shape, ElementLike } from 'diagram-js/lib/model/Types'
import Selection from 'diagram-js/lib/features/selection/Selection'
import CommandStack from 'diagram-js/lib/command/CommandStack'
import AlignElements from 'diagram-js/lib/features/align-elements/AlignElements'
import type { Alignment } from 'diagram-js/lib/features/align-elements/AlignElements'
import Modeling from 'bpmn-js/lib/features/modeling/Modeling.js'
import type ElementRegistry from 'diagram-js/lib/core/ElementRegistry'
import { useRoute, useRouter } from 'vue-router'
import { getFlowModelById, modelDesign } from '@/api/model'
import type { ModelDesignVo } from '@/types/process'

const bpmnCanvas = ref<HTMLDivElement>()
const modeler = ref<BpmnModeler>()
const moddle = new BpmnModdle()

// 添加模拟器状态
const simulationActive = ref(false)

// 修改 modeler 配置
const options: { [key: string]: unknown } = {}

options['minimap'] = {
  open: false,
  position: {
    x: 20,
    y: 'bottom',
  },
}

options['tokenSimulation'] = {
  active: false,
}

options['linting'] = {
  active: false,
  bpmnlint: bpmnlint,
}

options['gridLine'] = {
  smallGridSpacing: 20,
  gridSpacing: 80,
  gridLineStroke: 0.5,
  gridLineOpacity: 0.6,
  gridLineColor: '#ccc',
}

// 属性面板显示状态
const drawerVisible = ref(true)

// 当前选中的元素
const currentElement = ref<BpmnElement | undefined>(null)

// 切换属性面板显示状态
const toggleDrawer = () => {
  drawerVisible.value = !drawerVisible.value
}

// 监听元素选择
const handleElementSelect = (event: Shape | Element | Connection | Label | null) => {
  if (!modeler.value) return

  let activatedElement = event?.newSelection[0] || null

  if (!activatedElement) {
    activatedElement = modeler.value
      .get<ElementRegistry>('elementRegistry')
      .find((el: ElementLike) => el.type === 'bpmn:Process')
    if (!activatedElement) {
      console.log('No Element found!')
      return
    }
  }
  currentElement.value = markRaw(activatedElement)
}

const initModelerStr = (key?: string, name?: string) => {
  const timestamp = Date.now()
  const newId: string = `Process_${timestamp}`
  const newName: string = `业务流程_${timestamp}`
  const xmlString: string = xmlStr(key ? key : newId, name ? name : newName, 'flowable')
  return xmlString
}

const key = ref('')
const name = ref('')
const modelId = ref('')

const router = useRouter()

onMounted(async () => {
  const route = useRoute()
  modelId.value = route.query.id as string
  key.value = route.query.key as string
  name.value = route.query.name as string
  try {
    modeler.value = new BpmnModeler({
      container: bpmnCanvas.value,
      additionalModules: [
        translate,
        minimapModule,
        TokenSimulationModule,
        lintModule,
        CreateAppendAnythingModule,
        RewritePalette,
        EnhancementContextPad,
        GridLineModule,
        BpmnColorPickerModule,
        CustomRenderer,
        {
          __init__: ['flowableModdle'],
          flowableModdle: ['value', FlowableModdle],
        },
      ],
      moddleExtensions: {
        flowable: FlowableModdle,
      },
      ...options,
    })
    console.log('BPMN modeler initialized:', modeler.value)
    let modelStr = initModelerStr(key.value, name.value)
    if (modelId.value) {
      const { data } = await getFlowModelById(modelId.value as string)
      modelStr = data.xml || modelStr
    }
    modeler.value
      .importXML(modelStr)
      .then((result) => {
        const { warnings } = result
        console.log('success !', warnings)
      })
      .catch((error) => {
        const { warnings, message } = error
        console.log('something went wrong:', warnings, message)
      })
    // 添加元素选择事件监听
    modeler.value.on('selection.changed', handleElementSelect)
  } catch (error) {
    console.error('Error initializing BPMN modeler:', error)
  }
})

onBeforeUnmount(() => {
  // 移除事件监听
  if (modeler.value) {
    modeler.value.off('selection.changed', handleElementSelect)
  }
})

//对齐
const handleAlign = (type: Alignment) => {
  if (!modeler.value) return
  const modeling: Modeling | null = modeler.value.get('modeling')
  const selection: Selection | null = modeler.value.get('selection')
  const align: AlignElements = modeler.value.get('alignElements')
  if (modeling && selection) {
    const selectedElements = selection.get()
    if (!selectedElements || selectedElements.length <= 1) {
      ElMessage.warning('请按住 Shift 键选择多个元素对齐')
      return
    }
    align.trigger(selectedElements, type)
  }
}

// 视图控制
const zoom = (delta: number) => {
  if (!modeler.value) return
  const canvas = modeler.value.get<Canvas>('canvas')
  const currentZoom = canvas.zoom()
  canvas.zoom(currentZoom + delta)
}

const resetView = () => {
  if (!modeler.value) return
  const canvas = modeler.value.get<Canvas>('canvas')
  canvas.zoom('fit-viewport', { x: 0, y: 0 })
}

// 编辑控制
const undo = () => {
  if (!modeler.value) return
  modeler.value.get<CommandStack>('commandStack').undo()
}

const redo = () => {
  if (!modeler.value) return
  modeler.value.get<CommandStack>('commandStack').redo()
}

const resetBpmn = () => {
  if (!modeler.value) return
  modeler.value.importXML(initModelerStr(key.value, name.value))
}

// XML预览相关
const previewXMLVisible = ref(false)
const xmlContent = ref('')
const highlightedXML = computed(() => {
  if (!xmlContent.value) return ''
  return hljs.highlight(xmlContent.value, { language: 'xml' }).value
})

const previewXML = async () => {
  try {
    const xml = await modeler.value?.saveXML({ format: true })
    xmlContent.value = xml?.xml || ''
    previewXMLVisible.value = true
  } catch (error) {
    console.error('预览XML失败:', error)
    ElMessage.error('预览XML失败')
  }
}

// JSON预览相关
const previewJSONVisible = ref(false)
const jsonContent = ref('')
const highlightedJSON = computed(() => {
  if (!jsonContent.value) return ''
  return hljs.highlight(jsonContent.value, { language: 'json' }).value
})

const previewJSON = async () => {
  try {
    if (!modeler.value) return
    const result = await modeler.value.saveXML({ format: true })
    const jsonStr = await moddle.fromXML(result.xml!)
    const json = JSON.stringify(jsonStr, null, 2)
    jsonContent.value = json
    previewJSONVisible.value = true
  } catch (error) {
    console.error('预览JSON失败:', error)
    ElMessage.error('预览JSON失败')
  }
}

// 复制内容到剪贴板
const copyXML = () => {
  copyToClipboard(xmlContent.value)
}

const copyJSON = () => {
  copyToClipboard(jsonContent.value)
}
// 下载功能
const downloadFile = async (type: 'xml' | 'svg' | 'bpmn') => {
  try {
    let content: string
    let name = 'diagram'

    if (!modeler.value) return
    if (type === 'svg') {
      const { svg } = await modeler.value.saveSVG()
      content = svg
      name += '.svg'
    } else {
      const { xml } = await modeler.value.saveXML({ format: true })
      content = xml || ''
      name += type === 'bpmn' ? '.bpmn' : '.xml'
    }

    const blob = new Blob([content], { type: 'application/octet-stream' })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = name
    link.click()
    window.URL.revokeObjectURL(url)
  } catch (err) {
    console.error(err)
    ElMessage.error(`${type.toUpperCase()} 文件导出失败`)
  }
}

// 添加新的状态
const showShortcuts = ref(false)
const validateVisible = ref(false)
const validateErrors = ref<Array<ProcessError>>([])

// 处理文件上传
const handleFileUpload = async (file: File) => {
  try {
    const reader = new FileReader()
    reader.onload = async (e) => {
      const xml = e.target?.result as string
      try {
        if (!modeler.value) return
        await modeler.value.importXML(xml)
        ElMessage.success('导入成功')
      } catch (err) {
        console.error(err)
        ElMessage.error('导入失败：文件格式错误')
      }
    }
    reader.readAsText(file)
    return false
  } catch (err) {
    console.error(err)
    ElMessage.error('文件读取失败')
    return false
  }
}

// 定义接口
interface ProcessError {
  id: string
  message: string
}

// 流程校验
const validateProcess = async () => {
  try {
    if (!modeler.value) return
    validateErrors.value = []
    const linting = modeler.value.get('linting')
    const issues = await linting.lint()
    for (const key in issues) {
      if (issues.hasOwnProperty(key)) {
        issues[key].forEach((item: ProcessError) => {
          validateErrors.value.push({
            id: item.id,
            message: customTranslate(item.message),
          })
        })
      }
    }
    validateVisible.value = true
  } catch (err) {
    console.error(err)
    ElMessage.error('校验失败')
  }
}

// 定位错误元素
const locateElement = (elementId: string) => {
  if (!modeler.value) return
  // 获取元素注册表
  const elementRegistry = modeler.value.get<ElementRegistry>('elementRegistry')
  // 通过ID获取当前元素对象
  const element = elementRegistry.get(elementId)
  if (!element) return
  const canvas = modeler.value.get<Canvas>('canvas')
  canvas.scrollToElement(element)
  const selection: Selection = modeler.value.get('selection')
  selection.select(element)
}

// 小地图状态
const showMinimap = ref(false)

// 切换小地图显示状态
const toggleMinimap = () => {
  if (!modeler.value) return
  showMinimap.value = !showMinimap.value
  const minimap = modeler.value.get('minimap')
  minimap.toggle()
}

// 切换流程模拟器
const toggleSimulation = () => {
  if (!modeler.value) return
  simulationActive.value = !simulationActive.value
  const tokenSimulation = modeler.value.get<ToggleMode>('toggleMode')
  tokenSimulation.toggleMode()
}

// 提交流程设计
const submitDeploy = async () => {
  try {
    if (!modeler.value) return
    // 获取当前流程的 XML
    const { xml } = await modeler.value.saveXML({ format: true })
    const deployForm: ModelDesignVo = {
      id: modelId.value,
      xml: xml || '',
    }
    //todo: 调用流程设计接口
    await modelDesign(deployForm)
    ElMessage.success('流程设计成功')
  } catch (error) {
    console.error('流程设计失败:', error)
  }
}

// 返回列表页
const handleBack = () => {
  router.push('/process/design')
}
</script>

<style scoped>
.containers {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  background-color: #fff;
}

.canvas {
  flex: 1;
  height: 100%;
  position: relative;
  background: url('@/assets/images/diagram-bg.png') repeat;
}

/* 确保画布容器能够自适应父容器大小 */
:deep(.bjs-container) {
  width: 100% !important;
  height: 100% !important;
}

/* 确保画布能够自适应容器大小 */
:deep(.djs-container) {
  width: 100% !important;
  height: 100% !important;
}

/* 优化工具栏布局 */
.toolbar {
  position: absolute;
  top: 16px;
  left: 30px;
  transform: none;
  z-index: 3;
  display: flex;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.95);
  padding: 4px 12px;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(8px);
  transition: all 0.3s ease;
  border: 1px solid var(--el-border-color-lighter);
}

/* 优化属性面板过渡效果 */
.property-panel {
  position: relative;
  flex-shrink: 0;
  width: 420px;
  height: 100%;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  transform: translateX(100%);
  background-color: #fff;
  border-left: 1px solid var(--el-border-color-light);
}

.property-panel.panel-visible {
  transform: translateX(0);
}

.toolbar:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-1px);
}

.tool-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 2px;
}

.group-title {
  font-size: 11px;
  color: var(--el-text-color-secondary);
  margin-bottom: 2px;
  user-select: none;
  font-weight: 500;
}

.button-group {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2px;
}

:deep(.el-divider--vertical) {
  margin: 0 4px;
  height: 36px;
  border-color: var(--el-border-color-lighter);
}

/* 按钮样式优化 */
.el-button {
  margin: 0;
  padding: 4px;
  font-size: 14px;
  border-radius: 4px;
  transition: all 0.2s ease;
}

:deep(.el-button.is-circle) {
  width: 26px;
  height: 26px;
  padding: 4px;
}

/* 按钮激活状态 */
:deep(.el-button.is-active),
:deep(.el-button.el-button--primary) {
  background-color: var(--el-color-primary-light-8);
  border-color: var(--el-color-primary-light-5);
  color: var(--el-color-primary);
}

/* 按钮悬浮效果 */
:deep(.el-button:not(.is-active):hover) {
  background-color: var(--el-color-primary-light-9);
  border-color: var(--el-color-primary-light-5);
  color: var(--el-color-primary);
  transform: translateY(-1px);
}

/* 按钮点击效果 */
:deep(.el-button:active) {
  transform: translateY(1px);
}

/* 上传按钮样式优化 */
.upload-button {
  display: inline-block;
}

.upload-button :deep(.el-upload) {
  display: block;
}

.upload-button :deep(.el-button) {
  display: block;
}

.preview-header {
  margin-bottom: 16px;
  text-align: right;
}

.preview-content {
  max-height: 600px;
  overflow: auto;
  padding: 16px;
  background-color: #f8f9fa;
  border-radius: 8px;
  font-family: 'Fira Code', monospace;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  border: 1px solid #e4e7ed;
}

.preview-content::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.preview-content::-webkit-scrollbar-thumb {
  background: #dcdfe6;
  border-radius: 4px;
}

.preview-content::-webkit-scrollbar-track {
  background: #f8f9fa;
  border-radius: 4px;
}

:deep(.el-dialog) {
  border-radius: 8px;
  overflow: hidden;
}

:deep(.el-dialog__header) {
  margin: 0;
  padding: 20px 20px 10px;
  border-bottom: 1px solid #e4e7ed;
}

:deep(.el-dialog__body) {
  padding: 20px;
}

/* 开关样式优化 */
:deep(.el-switch) {
  margin: 8px 0;
  --el-switch-on-color: var(--el-color-primary);
}

/* 空状态样式优化 */
:deep(.el-empty) {
  padding: 40px 0;
  background-color: #f8f9fa;
  border-radius: 4px;

  .el-empty__description {
    margin-top: 16px;
    font-size: 13px;
    color: var(--el-text-color-secondary);
  }
}

/* 快捷键提示样式 */
.shortcut-tips {
  position: fixed;
  right: -300px;
  bottom: 20px;
  width: 280px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
  z-index: 100;
}

.tips-visible {
  right: 20px;
}

.tips-header {
  padding: 12px 16px;
  border-bottom: 1px solid var(--el-border-color-light);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.tips-content {
  padding: 12px;
}

.tip-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;

  &:last-child {
    margin-bottom: 0;
  }
}

.key {
  background: #f5f7fa;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: monospace;
  margin-right: 8px;
  font-size: 12px;
}

.desc {
  color: var(--el-text-color-regular);
  font-size: 13px;
}

/* 校验结果样式 */
.validate-result {
  max-height: 400px;
  overflow: auto;
}

.error-item {
  margin-bottom: 8px;
  cursor: pointer;

  &:last-child {
    margin-bottom: 0;
  }

  :deep(.el-alert) {
    transition: all 0.3s;

    &:hover {
      transform: translateX(4px);
    }
  }
}

:deep(.djs-minimap) {
  div.toggle {
    display: none;
  }
  right: unset;
  top: unset;
  left: 80px;
  bottom: 30px;
}

/* 添加模拟器相关样式 */
:deep(.bts-toggle-mode) {
  display: none !important;
}

:deep(.bts-simulation-header) {
  background: linear-gradient(to right, #f8f9fa, #fff) !important;
  border-bottom: 1px solid var(--el-border-color-light) !important;
  padding: 8px 16px !important;
}

:deep(.bts-simulation-header button) {
  background: transparent !important;
  border: 1px solid var(--el-border-color) !important;
  border-radius: 4px !important;
  padding: 4px 8px !important;
  color: var(--el-text-color-regular) !important;
  transition: all 0.3s !important;
}

:deep(.bts-simulation-header button:hover) {
  background: var(--el-color-primary-light-9) !important;
  border-color: var(--el-color-primary) !important;
  color: var(--el-color-primary) !important;
}

:deep(.bts-simulation-header button.active) {
  background: var(--el-color-primary) !important;
  border-color: var(--el-color-primary) !important;
  color: white !important;
}

:deep(.token-simulation-palette) {
  border: none !important;
  background: transparent !important;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1) !important;
  border-radius: 8px !important;
  padding: 8px !important;
}

:deep(.token-simulation-palette button) {
  border-radius: 4px !important;
  transition: all 0.3s !important;
}

:deep(.token-simulation-palette button:hover) {
  background: var(--el-color-primary-light-9) !important;
}

/* 添加画布阴影效果 */
:deep(.djs-container) {
  background-color: transparent !important;
}

:deep(.djs-palette) {
  background: rgba(255, 255, 255, 0.9) !important;
  border: 1px solid #e4e7ed !important;
  border-radius: 4px;
  top: 100px !important;
}

/* 优化连线样式 */
:deep(.djs-connection) {
  path {
    stroke-width: 2px !important;
  }

  &.selected path,
  &:hover path {
    stroke-width: 3px !important;
  }
}

/* 优化节点样式 */
:deep(.djs-element) {
  &.selected,
  &:hover {
    .djs-visual > :nth-child(1) {
      stroke-width: 3px !important;
    }
  }
}

/* 优化节点文本样式 */
:deep(.djs-label) {
  font-family: var(--el-font-family) !important;
  font-size: 13px !important;
  color: var(--el-text-color-primary) !important;
}

/* 优化锚点样式 */
:deep(.djs-connection-point),
:deep(.djs-bendpoint) {
  visibility: hidden;
}

:deep(.selected .djs-connection-point),
:deep(.selected .djs-bendpoint),
:deep(.djs-bendpoint:hover),
:deep(.djs-segment-dragger:hover),
:deep(.djs-connection-point:hover) {
  visibility: visible;
}

/* 优化对齐线样式 */
:deep(.djs-snapping-line) {
  stroke: var(--el-color-primary) !important;
  stroke-width: 1px !important;
  stroke-dasharray: 5, 5 !important;
}

/* 优化选择框样式 */
:deep(.djs-lasso-overlay) {
  fill: var(--el-color-primary-light-8);
  stroke: var(--el-color-primary);
  stroke-width: 1px;
  stroke-dasharray: 5, 5;
  fill-opacity: 0.1;
}

/* 优化滚动条样式 */
:deep(.djs-container)::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

:deep(.djs-container)::-webkit-scrollbar-thumb {
  background: #dcdfe6;
  border-radius: 4px;
}

:deep(.djs-container)::-webkit-scrollbar-track {
  background: transparent;
}

/* 优化画布交互效果 */
:deep(.djs-container) {
  &.is-dragging {
    cursor: grabbing !important;
  }

  &:not(.is-dragging) {
    cursor: default !important;
  }
}

:deep(.el-select) {
  width: 100%;
}

.preview-dialog {
  :deep(.el-dialog__body) {
    padding: 20px;
  }
}

.xml-content,
.json-content {
  margin: 0;
  padding: 16px;
  background-color: #f8f9fa;
  border-radius: 4px;
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-all;

  :deep(code) {
    font-family: inherit;
  }

  /* 高亮样式优化 */
  :deep(.hljs) {
    background: transparent;
    padding: 0;
  }

  :deep(.hljs-tag) {
    color: #22863a;
  }

  :deep(.hljs-name) {
    color: #22863a;
  }

  :deep(.hljs-attr) {
    color: #6f42c1;
  }

  :deep(.hljs-string) {
    color: #032f62;
  }

  :deep(.hljs-keyword) {
    color: #d73a49;
  }
}

.json-content {
  :deep(.hljs-property) {
    color: #005cc5;
  }

  :deep(.hljs-string) {
    color: #032f62;
  }

  :deep(.hljs-number) {
    color: #005cc5;
  }

  :deep(.hljs-boolean) {
    color: #005cc5;
  }
}

/* 优化返回按钮样式 */
:deep(.el-button.back-button) {
  color: var(--el-color-primary);
}

:deep(.el-button.back-button:hover) {
  background-color: var(--el-color-primary-light-9);
  border-color: var(--el-color-primary-light-5);
}
</style>
